﻿#region 命名空间

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using Unity.Interception.InterceptionBehaviors;
using Unity.Interception.PolicyInjection.Pipeline;

#endregion

namespace Sharp.Infrastructure.Crosscutting
{
    /// <summary>
    ///     表示用于异常日志记录的拦截行为。
    /// </summary>
    public class ExceptionLoggingBehavior : IInterceptionBehavior
    { 
        /// <summary>
        ///     获取当前行为需要拦截的对象类型接口。
        /// </summary>
        /// <returns>所有需要拦截的对象类型接口。</returns>
        public IEnumerable<Type> GetRequiredInterfaces()
        {
            return Type.EmptyTypes;
        }

        /// <summary>
        ///     通过实现此方法来拦截调用并执行所需的拦截行为。
        /// </summary>
        /// <param name="input">调用拦截目标时的输入信息。</param>
        /// <param name="getNext">通过行为链来获取下一个拦截行为的委托。</param>
        /// <returns>从拦截目标获得的返回信息。</returns>
        [DebuggerStepThrough]
        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            var result = getNext().Invoke(input, getNext);

            if (result.Exception != null)
            {
                LogHelper.Error(result.Exception);

                if (((MethodInfo)(input.MethodBase)).ReturnType == typeof(Result))
                {
                    Result res = new Result
                    {
                        Err = result.Exception.Message
                    };

                    return input.CreateMethodReturn(res, new object[] { input.Arguments });
                }

                //ExceptionPolicy.HandleException(ex, this.PolicyName);

                
                throw result.Exception;
            }
            return result;
        }

        /// <summary>
        ///     获取一个<see cref="Boolean" />值，该值表示当前拦截行为被调用时，是否真的需要执行
        ///     某些操作。
        /// </summary>
        public bool WillExecute
        {
            get { return true; }
        }
         
    }
}